import React, { useState, useEffect, useRef } from 'react';
import { Modal, Button, Spinner } from 'react-bootstrap';

interface ApiResponse {
  data: null;
  status: string;
}

const ModalWithApi: React.FC = () => {
  const [showModal, setShowModal] = useState(false);
  const [apiData, setApiData] = useState<ApiResponse | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const abortControllerRef = useRef<AbortController | null>(null);

  // 打开弹窗并触发 API 请求
  const handleOpenModal = () => {
    setShowModal(true);
  };

  // 关闭弹窗并取消 API 请求
  const handleCloseModal = () => {
    // 取消正在进行的 API 请求
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    
    // 重置状态
    setApiData(null);
    setIsLoading(false);
    setError(null);
    setShowModal(false);
  };

  // 弹窗显示时自动触发 API 请求
  useEffect(() => {
    if (showModal) {
      fetchData();
    }
  }, [showModal]);

  // API 请求逻辑
  const fetchData = async () => {
    setIsLoading(true);
    setError(null);
    
    // 创建新的 AbortController
    const controller = new AbortController();
    abortControllerRef.current = controller;

    try {
      const response = await fetch('https://api.example.com/data', {
        signal: controller.signal, // 关联 signal 到请求
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json() as ApiResponse;
      setApiData(data);
    } catch (err: unknown) {
      // 处理取消请求的错误
      if (err instanceof Error && err.name === 'AbortError') {
        console.log('API 请求已取消');
      } else {
        setError(err instanceof Error ? err.message : '发生未知错误');
      }
    } finally {
      setIsLoading(false);
      // 请求完成后重置 controller
      if (abortControllerRef.current === controller) {
        abortControllerRef.current = null;
      }
    }
  };

  return (
    <>
      <Button variant="primary" onClick={handleOpenModal}>
        打开弹窗并请求 API
      </Button>

      <Modal show={showModal} onHide={handleCloseModal}>
        <Modal.Header closeButton>
          <Modal.Title>API 请求示例</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {isLoading ? (
            <div className="d-flex justify-content-center">
              <Spinner animation="border" role="status">
                <span className="visually-hidden">加载中...</span>
              </Spinner>
            </div>
          ) : error ? (
            <div className="text-danger">{error}</div>
          ) : apiData ? (
            <div>
              <h5>API 响应数据</h5>
              <pre>{JSON.stringify(apiData, null, 2)}</pre>
            </div>
          ) : (
            <div>等待 API 响应...</div>
          )}
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleCloseModal}>
            关闭
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
};

export default ModalWithApi;  